/**
 * Copyright 2009-2010 - YangJiandong(chunquedong)
 * 
 * This file is part of ChunMap project
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE(Version >=3)
 * 你可以自由复制、传播本项目的下载包文件，但必须保持其完整性。
 * 我们不用对使用中的风险及由此造成的损失承担任何责任。
 * 详细情况请见《ChunMap许可协议》。

 * 想了解更多有关ChunMap的信息，请访问http://code.google.com/p/chunmap/
 */
package chunmap.view.render;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.GeneralPath;
import java.util.ArrayList;
import java.util.List;

import chunmap.data.feature.Feature;
import chunmap.data.feature.Shape;
import chunmap.model.coord.Coordinate2D;
import chunmap.model.coord.Position;
import chunmap.model.crs.transf.AffineTransform;
import chunmap.model.elem.LineSegment;
import chunmap.model.elem.Vector;
import chunmap.model.geom.Geometry;
import chunmap.model.geom.GeometryCollection;
import chunmap.model.geom.LineString;
import chunmap.model.geom.Ring;
import chunmap.model.geom.Polygon;
import chunmap.view.View;

/**
 * @author chunquedong
 * 
 */
public class ArrowSymbol extends Symbol {

	private Geometry geometry;
	private final Color color;
	private final int dis=20;

	public ArrowSymbol() {
		this(Color.black);
	}
	
	public ArrowSymbol(Color color){
		this(color,12,4);
	}

	public ArrowSymbol(Color color,int w,int h) {
		this.color = color;
		
		List<Position> points = new ArrayList<Position>();
		Position p1 = new Coordinate2D(-w, h);
		Position p2 = new Coordinate2D(0, 0);
		Position p3 = new Coordinate2D(-w, -h);
		points.add(p1);
		points.add(p2);
		points.add(p3);

		LineString ls = new LineString(points);
		geometry = ls;
	}

	private Geometry getGeometry(Position p1, Position p2) {

		Vector v1 = new Vector(p1, p2);
		Vector v2 = new Vector(new Coordinate2D(0, 0), new Coordinate2D(0, 1));
		double angle = v1.computeAngle(v2);
		AffineTransform transf = AffineTransform.rotate(0, 0, angle + Math.PI
				/ 2d);
		AffineTransform transf2 = transf.accumulate(AffineTransform.pan(p2
				.getX(), p2.getY()));
		return geometry.transform(transf2);
	}

	public void draw(Graphics g, Feature f, View renderer) {
		Geometry geo=((Shape)f).getGeometry().transform(renderer.world2Screen());
		drawGeo(g,geo,renderer);
	}
	
	public void drawGeo(Graphics g, Geometry geo, View renderer) {
		if (geo instanceof LineString) {
			LineString ls = (LineString) geo;
			drawLineSymbol((Graphics2D) g, ls);
		} else if (geo instanceof Polygon) {
			Polygon pg = (Polygon) geo;
			drawLineSymbol((Graphics2D) g, pg.getShell());
			for (Ring r : pg.getHoles()) {
				drawLineSymbol((Graphics2D) g, r);
			}
		} else if (geo instanceof GeometryCollection) {
			GeometryCollection gs = (GeometryCollection) geo;
			for (Geometry ge : gs) {
				drawGeo(g, ge, renderer);
			}
		}
	}

	private void drawLineSymbol(Graphics2D g, LineString ls) {

		g.setPaint(color);
		for (int i = 0, n = ls.size() - 1; i < n; i++) {
			Position p1 = ls.getPoint(i);
			Position p2 = ls.getPoint(i + 1);

			// 距离过小时不画
			LineSegment lseg = new LineSegment(p1, p2);
			if (lseg.taxiDistance() < dis)
				continue;

			LineString lsa = (LineString) getGeometry(p1, p2);
			GeneralPath path = toGeneralPath(lsa);
			g.fill(path);
		}

	}

	private GeneralPath toGeneralPath(LineString ls) {
		GeneralPath path = new GeneralPath();
		path.moveTo(ls.firstPoint().getX(), ls.firstPoint().getY());
		for (int i = 1, n = ls.size(); i < n; i++) {
			Position p = ls.getPoint(i);
			path.lineTo(p.getX(), p.getY());
		}
		return path;
	}

}
